<script setup lang="ts">
import { EmptyEnum, EmptyState } from '@yk/components/empty-box/type'
import YkEmptyBox from '@yk/components/empty-box/YkEmptyBox.vue'
import { initAMap } from '@utils/amap'
import { PromiseType } from '@/typings'
import { createVNode, render } from 'vue'
import { FnOperationControl } from '@utils/object-util/periodic-execution/FnOperationControl'
import { createFitViewOverlays } from '@utils/amap/utils'
import { IndexCountDTO } from '@/api/entity/home'
import { homeDataGatewayAPI, homeDataStatisticsAPI } from '@/api/home'
import { getAlarmListByPageAPI } from '@/api/alarm'
import { AlarmHistoryDTO } from '@/api/entity/alarm'
import { getLogListByPageAPI } from '@/api/log'
import { GatewayDTO } from '@/api/entity/gateway'
import { useAppStore } from '@/pinia'
import { getAnnouncementListAPI } from '@/api/notice'
import { FileUtil, MountedCheck } from '@/utils'
import { Announcement } from '@/api/entity/notice'
import { InfoFilled } from '@element-plus/icons-vue'
import { TabBarUtil } from '@/layout/components/tab-bar'

defineOptions({ name: 'BoardIndex' })
const router = useRouter()
const appStore = useAppStore()

const mc = new MountedCheck()
onMounted(() => {
  reload()
  // 网关分布
  loadMap()
  // 公告
  getAnnouncementList()
  mc.end()
})

onActivated(() => {
  if (mc.isMounted()) return
  reload()
  operationControl.run()
})

onDeactivated(() => {
  operationControl.stop()
})

function reload () {
  // 获取资产信息
  getPropertyInfo()
  // 最新报警信息
  getAlarmInfo()
  // 设备日志
  getDeviceLog()
}

// region TODO 资产信息
const propertyInfo = shallowRef<IndexCountDTO>({})
function getPropertyInfo () {
  homeDataStatisticsAPI().then((res) => {
    res.result().then((rdata) => {
      propertyInfo.value = rdata.data
    })
  })
}
// endregion

// region TODO 公告
const announcementsList = shallowRef<Announcement[]>([])
function getAnnouncementList () {
  getAnnouncementListAPI({ status: '0' }).then((res) => {
    res.result().then((rdata) => {
      announcementsList.value = rdata.data || []
    })
  })
}
function announcementItemClickHandle (item: Announcement) {
  if (item.link) {
    window.open(item.link, '_blank')
  }
}
// endregion

// region TODO 最新报警信息
const alarmInfoState = ref<EmptyState>(EmptyEnum.NONE)
const alarmInfoList = shallowRef<AlarmHistoryDTO[]>([])
// 获取报警信息
function getAlarmInfo () {
  alarmInfoState.value = EmptyEnum.LOADING
  getAlarmListByPageAPI({
    param: { alarmState: true },
    pageNum: 1,
    pageSize: 20
  }).finally(() => {
    alarmInfoState.value = EmptyEnum.NONE
  }).then((res) => {
    res.result().then((rdata) => {
      const data = rdata.records || []
      if (data.length) {
        alarmInfoList.value = data
        alarmInfoState.value = EmptyEnum.SUCCESS
      } else {
        alarmInfoState.value = { type: EmptyEnum.EMPTY_TIP, description: '设备很健康，暂无报警' }
      }
    })
  })
}
// endregion

// region TODO 设备日志
const deviceLogState = ref<EmptyState>(EmptyEnum.NONE)
const deviceLogList = shallowRef([])
// 获取设备日志
function getDeviceLog () {
  deviceLogState.value = EmptyEnum.LOADING
  getLogListByPageAPI({
    param: { type: 1 },
    pageSize: 20,
    pageNum: 1
  }).finally(() => {
    deviceLogState.value = EmptyEnum.NONE
  }).then((res) => {
    res.result().then((rdata) => {
      const data = rdata.records || []
      if (data.length) {
        deviceLogList.value = data
        deviceLogState.value = EmptyEnum.SUCCESS
      } else {
        deviceLogState.value = { type: EmptyEnum.EMPTY, description: '设备很稳定，暂无日志' }
      }
    })
  })
}
// endregion

// region TODO 网关分布 - Map
const mapRef = shallowRef<HTMLDivElement>()
let aMap: PromiseType<ReturnType<typeof initAMap>> = null

// 加载地图
function loadMap () {
  initAMap({
    el: mapRef.value,
    plugins: ['AMap.MarkerCluster']
  }).then(async (res) => {
    aMap = res
    await loadCluster()
    initInfoWindow()
    aMap.map.on('click', (e) => {
      console.log(e.lnglat.lng, e.lnglat.lat)
    })
  })
}

// region TODO 聚合标记
let cluster: AMap.MarkerCluster = null
// 加载聚合标记
async function loadCluster () {
  await import('~icons/traffic/location-pedestal2').then((e) => {
    const div = document.createElement('div')
    render(createVNode(e.default), div)
    iconSvgStr = div.innerHTML
  })
  cluster = new AMap.MarkerCluster(aMap.map, [], {
    gridSize: 50,
    maxZoom: 13,
    renderMarker (e) {
      const status = e.data[0].status
      const marker = e.marker
      const icon = getMaskerIcon()
      icon.style.color = { 1: '#1570BB', 2: '#86909C', 3: '#FC5555' }[status] || 'black'
      marker.setContent(icon)
      marker.on('click', () => {
        openInfoWindow(e.data[0])
      })
    }
  })
  startRealTimeGatewayList()
}
// 设置聚合数据
function setClusterData (isFitView = false, _data: GatewayDTO[]) {
  const data = _data.reduce((ret, item) => {
    if (item.latitudeLongitude) {
      const status = item.alarmStatus ? 3 : item.status ? 1 : 2
      ret.push({ lnglat: item.latitudeLongitude.split(','), data: item, status })
    }
    return ret
  }, [])

  isFitView && data.length && aMap.map.setFitView(createFitViewOverlays(aMap.AMap, data))
  cluster.setData(data)
}
// 点标记图标
let iconSvgStr: string = null
function getMaskerIcon () {
  const div = document.createElement('div')
  div.style.width = '20px'
  div.style.height = '28px'
  div.innerHTML = iconSvgStr
  div.firstElementChild.setAttribute('width', '100%')
  div.firstElementChild.setAttribute('height', '100%')
  return div
}
// endregion

// region TODO 网关数据
const gatewayStatusStatistics = shallowRef({
  // 报警数量
  alarmCount: 0,
  // 离线数量
  offlineCount: 0,
  // 在线数量
  onlineCount: 0
})
// 获取网关列表
async function getGatewayList (e: { isFirstRun: boolean }) {
  homeDataGatewayAPI().then((res) => {
    res.result().then((rdata) => {
      const data = rdata.data || {}
      gatewayStatusStatistics.value = data as any
      setClusterData(e.isFirstRun, data.gatewayList || [])
    })
  })
}

// 定时请求
let operationControl: FnOperationControl = null
// 开始获取网关实时数据
function startRealTimeGatewayList () {
  operationControl = new FnOperationControl({
    fn: getGatewayList, timeout: 5000
  })
}
onUnmounted(() => {
  operationControl && operationControl.stop()
})
// endregion

// region TODO 信息窗口
const mapInfoWindowRef = shallowRef<HTMLDivElement>()
const infoWindowData = ref<GatewayDTO>({})
let infoWindow: AMap.InfoWindow = null
function initInfoWindow () {
  infoWindow = new AMap.InfoWindow({
    isCustom: true,
    anchor: 'top-left',
    closeWhenClickMap: true,
    offset: new AMap.Pixel(0, 0)
  })
  infoWindow.setContent(mapInfoWindowRef.value)
}
function openInfoWindow (masterData) {
  infoWindowData.value = masterData.data
  infoWindow.open(aMap.map, masterData.lnglat)
}
// function closeInfoWindow () {
//   infoWindowData.value = {}
//   infoWindow.close()
// }
// endregion
onBeforeUnmount(() => {
  aMap.map.destroy()
})
// endregion

// region TODO 跳转
// 网关
function toGateway (id: string) {
  TabBarUtil.value.reopen({ name: 'GatewayManage', params: { id } })
}
// endregion
const svg = '<path class="path" fill="none" stroke="red" d="M0,0 L0,50 L50,50 L50,0 Z">'
</script>

<template>
  <div :element-loading-svg="svg" class="layout_view h-100" style="min-height: 786px">
    <!--第一行 资产 & 公告-->
    <div class="d-flex" style="height: 154px;">
      <!--资产-->
      <div class="flex-1 c_card-white d-flex flex-column">
        <div style="height: 28px" class="fs-18 fw-7">👏 欢迎回来，{{ appStore.userInfo.phone }}</div>
        <div class="mt-8 flex-1 property-info">
          <!--接入网关-->
          <div class="property-info__item">
            <div class="icon"><ic-device-gateway /></div>
            <div>
              <div class="title">接入网关</div>
              <div class="data-box">
                <span class="value">{{ propertyInfo.gatewayCount }}</span>
                <span class="unit">个</span>
              </div>
            </div>
          </div>
          <!--接入设备-->
          <div class="property-info__item">
            <div class="icon"><ic-device-device /></div>
            <div>
              <div class="title d-flex-center">
                <span>接入设备</span>
                <el-tooltip content="接入设备包含分享设备" placement="top-start">
                  <el-icon size="14" class="color-secondary ml-1"><InfoFilled /></el-icon>
                </el-tooltip>
              </div>
              <div class="data-box">
                <span class="value">{{ propertyInfo.deviceCount }}</span>
                <span class="unit">个</span>
              </div>
            </div>
          </div>
          <!--接入摄像头-->
          <div class="property-info__item">
            <div class="icon"><ic-device-camera /></div>
            <div>
              <div class="title">接入摄像头</div>
              <div class="data-box">
                <span class="value">{{ propertyInfo.videoCount }}</span>
                <span class="unit">个</span>
              </div>
            </div>
          </div>
          <!--组态画面-->
          <div class="property-info__item">
            <div class="icon"><ic-data-doc /></div>
            <div>
              <div class="title">组态画面</div>
              <div class="data-box">
                <span class="value">{{ propertyInfo.configurationCount }}</span>
                <span class="unit">个</span>
              </div>
            </div>
          </div>
        </div>
      </div>
      <!--公告-->
      <div class="ml-12 overflow-hidden" style="width: 336px;border-radius: 4px;">
        <el-carousel trigger="click" height="154px" :interval="5000">
          <el-carousel-item v-for="item in announcementsList" :key="item.id">
            <img
              class="wh-100 " :class="{ 'cursor-pointer': item.link }" :src="FileUtil.prefixImage(item.url)"
              alt="" @click="announcementItemClickHandle(item)"
            >
          </el-carousel-item>
        </el-carousel>
      </div>
    </div>

    <!--第二行 统计 & 快捷入口-->
    <div class="d-flex mt-12" style="height: 136px;">
      <!--统计-->
      <div class="flex-1 c_card-white d-flex statistics">
        <div class="statistics__item flex-1">
          <div class="title d-flex-align-center">
            <span>设备在线率</span>
            <el-tooltip content="设备在线率包含分享设备" placement="top-start">
              <el-icon size="14" class="color-secondary ml-1"><InfoFilled /></el-icon>
            </el-tooltip>
          </div>
          <div class="value">{{ propertyInfo.onlineCount }}</div>
        </div>
        <div class="statistics__item flex-1 ml-12">
          <div class="title">设备报警数</div>
          <div class="value">{{ propertyInfo.alarmCount }}</div>
        </div>
        <div class="statistics__item flex-1 ml-12">
          <div class="title">存储型变量</div>
          <div class="value">{{ propertyInfo.variableCount }}</div>
        </div>
        <div class="statistics__item flex-1 ml-12">
          <div class="title">变量模板</div>
          <div class="value">{{ propertyInfo.templateCount }}</div>
        </div>
      </div>
      <!--快捷入口-->
      <div class="ml-12 c_card-white" style="width: 336px">
        <div class="c_card_header c_card-title">快捷入口</div>
        <div class="fast-list" style="height: var(--card-body-height)">
          <div class="fast-list__item" @click="router.push({ path: '/data/device/realtime' })">
            <div class="icon">
              <ic-traffic-building-line />
            </div>
            <div class="title">实时数据</div>
          </div>
          <div class="fast-list__item" @click="router.push({ path: '/data/device/history' })">
            <div class="icon">
              <ic-data-layers />
            </div>
            <div class="title">历史数据</div>
          </div>
          <div class="fast-list__item" @click="router.push({ path: '/alarm/alarm-report' })">
            <div class="icon">
              <ic-data-word-collect />
            </div>
            <div class="title">报警记录</div>
          </div>
          <div class="fast-list__item" @click="router.push({ path: '/video/index' })">
            <div class="icon">
              <ic-data-layers />
            </div>
            <div class="title">摄像头</div>
          </div>
        </div>
      </div>
    </div>

    <!--第三行 数据 & 网关-->
    <div class="d-flex mt-12" style="height: calc(100% - 314px)">
      <!--数据-->
      <div class="d-flex flex-column" style="width: 468px">
        <!--最新报警信息-->
        <div class="c_card-white flex-1 overflow-hidden">
          <div class="c_card_header">
            <div class="c_card-title">最新报警信息</div>
            <div class="c_header_right">
              <el-link href="/#/alarm/alarm-report" type="primary" class="fs-12">
                <span class="color-primary">查看更多</span>
              </el-link>
            </div>
          </div>
          <yk-empty-box :state="alarmInfoState" style="height: var(--card-body-height)">
            <div class="overflow-auto h-100">
              <div class="alarm-list">
                <div v-for="item in alarmInfoList" :key="item" class="alarm-list__item">
                  <div>
                    <el-tag type="danger" effect="dark" size="small">报警</el-tag>
                    <span class="name">【{{ item.deviceName }}】-{{ item.variableName }}</span>
                  </div>
                  <div class="mt-2">
                    <span class="value">报警值：{{ item.alarmValue }}</span>
                    <span class="time">报警时间：{{ item.alarmAt }}</span>
                  </div>
                </div>
              </div>
            </div>
          </yk-empty-box>
        </div>
        <!--设备日志-->
        <div class="c_card-white mt-12 flex-1 overflow-hidden">
          <div class="c_card_header ">
            <div class="c_card-title">设备日志</div>
            <div class="c_header_right">
              <el-link href="/#/log/index" type="primary" class="fs-12">
                <span class="color-primary">查看更多</span>
              </el-link>
            </div>
          </div>
          <yk-empty-box :state="deviceLogState" style="height: var(--card-body-height)">
            <div class="overflow-auto h-100">
              <div class="log-list">
                <div v-for="item in deviceLogList" :key="item" class="log-list__item">
                  <div>
                    <el-tag v-if="item.businessType == 4" type="success" size="small">上线</el-tag>
                    <el-tag v-if="item.businessType == 5" type="info" size="small">下线</el-tag>
                    <span class="name">{{ item.message }}</span>
                  </div>
                  <span class="time">{{ item.createdAt }}</span>
                </div>
              </div>
            </div>
          </yk-empty-box>
        </div>
      </div>
      <!--网关-->
      <div class="flex-1 ml-12 c_card-white">
        <div class="c_card_header c_card-title">网关分布</div>
        <div class="position-relative" style="height: var(--card-body-height)">
          <!--地图-->
          <div ref="mapRef" class="wh-100 bg-color-info" />
          <!--图例-->
          <div class="map-legend position-absolute">
            <div class="map-legend__item">
              <span class="title">在线</span>
              <span class="value">{{ gatewayStatusStatistics.onlineCount || 0 }}</span>
            </div>
            <div class="map-legend__item">
              <span class="title">离线</span>
              <span class="value">{{ gatewayStatusStatistics.offlineCount || 0 }}</span>
            </div>
            <div class="map-legend__item">
              <span class="title">报警</span>
              <span class="value">{{ gatewayStatusStatistics.alarmCount || 0 }}</span>
            </div>
          </div>
          <!-- 信息窗口 -->
          <div hidden>
            <div ref="mapInfoWindowRef" class="c_card-white map__info-window" style="width: 285px;min-height: 165px;">
              <div class="c_card_header bor-divider-b fw-4 d-flex-between-center">
                <div class="d-flex-align-center">
                  <img src="./images/map__info-window.png" alt="" class="c_header_icon" style="width: 10px;height: 10px;">
                  <div class="c_card-title">{{ infoWindowData.name }}</div>
                </div>
                <el-link type="primary" style="white-space: nowrap;" @click="toGateway(infoWindowData.id)">前往</el-link>
              </div>
              <!--网关状态-->
              <div class="info-item">
                <span class="label">网关状态：</span>
                <span class="value">{{ infoWindowData.status ? '在线' : '离线' }}</span>
              </div>
              <!--网关位置-->
              <div class="info-item">
                <span class="label">网关位置：</span>
                <span class="value">{{ infoWindowData.address }}</span>
              </div>
              <!--报警状态-->
              <div class="info-item">
                <span class="label">报警状态：</span>
                <span class="value">{{ infoWindowData.alarmStatus ? '报警' : '无' }}</span>
              </div>
            </div>
          </div>
        </div>
      </div>
    </div>
  </div>
</template>

<style scoped lang="scss">
//.abcd {
//  .adb {
//    display: grid;
//    overflow: hidden;
//    grid-template-rows: 0fr;
//    transition: all 0.2s;
//    > div{
//      min-height: 0;
//    }
//  }
//  &:hover .adb {
//    grid-template-rows: 1fr;
//  }
//}
// 资产
.property-info {
  display: flex;
  margin: 0 -12px;
  .property-info__item {
    flex: 1;
    position: relative;
    padding: 20px;
    display: flex;
    color: var(--el-text-color-primary);
    &:not(:last-child) {
     margin-right: 20px;
      // 分割线
     &:after {
       content: " ";
       display: inline-block;
       width: 1px;
       height: 62px;
       background-color: var(--yk-color-divider);
       position: absolute;
       inset: 0 0 0 auto;
       margin: auto 0;
     }
   }
    .icon {
      width: 54px;
      height: 54px;
      border-radius: 50%;
      background: #F6F7FB;
      color: var(--yk-color-primary);
      margin-right: 12px;
      font-size: 28px;
      display: flex;
      align-items: center;
      justify-content: center;
    }
    .title {
      font-size: 12px;
    }
    .data-box {
      margin-top: 6px;
      .value {
        font-size: 22px;
        font-weight: bold;
      }
      .unit {
        font-size: 12px;
      }
    }
  }
}

// 统计
.statistics {
  .statistics__item {
    padding: 27px 0 0 18px;
    background: #F7F8FA url("@images/card/card-decorate-down.png") right bottom no-repeat;
    .title {
      font-size: 14px;
      color: var(--el-text-color-primary);
    }
    .value {
      font-size: 24px;
      color: var(--yk-color-primary);
      margin-top: 4px;
      font-weight: bold;
    }
  }
}

// 快捷入口
.fast-list {
  display: flex;
  .fast-list__item {
    flex: 1;
    @include d-flex(center);
    flex-direction: column;
    cursor: pointer;
    .icon {
      width: 32px;
      aspect-ratio: 1;
      border-radius: 6px;
      background: #F7F8FA;
      @include d-flex(center);
      font-size: 18px;
    }
    .title {
      font-size: 12px;
      color: #424E66;
      margin-top: 4px;
    }
  }
}

// 最新报警信息
.alarm-list {
  .alarm-list__item {
    height: 56px;
    border-bottom: 1px solid var(--yk-color-divider);
    margin-bottom: 12px;
    .name {
      font-size: 14px;
      color: var(--el-text-color-primary);
      margin-bottom: 6px;
      margin-left: 4px;
    }
    .value {
      font-size: 12px;
      color: var(--el-text-color-primary);
    }
    .time {
      font-size: 12px;
      margin-left: 24px;
      color: var(--yk-color-secondary);
    }
  }
}

// 设备日志
.log-list {
  .log-list__item {
    @include d-flex(center, space-between);
    height: 46px;
    border-bottom: 1px solid var(--yk-color-divider);
    .name {
      font-size: 14px;
      color: var(--el-text-color-primary);
      margin-left: 12px;
    }
    .time {
      font-size: 12px;
      color: var(--yk-color-secondary);
    }
  }
}

//网关分布 - 图例
.map-legend {
  width: 131px;height: 126px;
  top: 12px;left: 12px;
  background: #F6F8F9;
  border-radius: 4px;
  padding: 16px 24px;
  display: flex;
  flex-direction: column;
  justify-content: space-between;
  .map-legend__item {
    height: 21px;
    color: var(--el-text-color-primary);
    .title {
      font-size: 14px;
      display: inline-flex;
      align-items: center;
      &:before {
        content: " ";
        display: inline-block;
        width: 12px;
        height: 12px;
        border-radius: 6px;
        margin-right: 16px;
      }
      &:after {
        content: " ";
        display: inline-block;
        width: 2px;
        height: 13px;
        background-color: #E1E5F4;
        margin-left: 8px;
      }
    }
    .value {
      display: inline-block;
      width: 16px;
      text-align: right;
    }
    &:nth-child(1) .title:before {
      background-color: var(--yk-color-primary);
    }
    &:nth-child(2) .title:before {
      background-color: var(--yk-color-secondary);
    }
    &:nth-child(3) .title:before {
      background-color: var(--yk-color-danger);
    }
  }
}
// 网关布局 - 地图信息窗体
.map__info-window {
  .info-item {
    margin-top: 12px;
    .label {
      font-size: 14px;
      color: #9E9E9E;
    }
    .value {
      font-size: 14px;
      color: #131414;
    }
  }

}
</style>
